/** 
 *  @file       ds1302.c
 *  @brief       ds1302驱动程序
 *  @author     Z B T   
 *  @version    V0.1
 *  @date       2015-10
 */
 
#include "ds1302.h"
#include "delay.h"
#include "config.h"

sbit DS_IO  = P3^4;       /**< DS1302使用的IO */
sbit DS_RST = P3^5;
sbit DS_CLK = P3^6;

/** 顺序：  秒 分 时 日 月 周 年 */
unsigned char code read_addr[]  = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
unsigned char code write_addr[] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

extern unsigned char time_buff[];

static void ds1302_write(unsigned char addr, unsigned char dat);
static unsigned char ds1302_read(unsigned char addr);

/**
 *  DS1302初始化
 *  @param None
 *  @return None
 */
void ds1302_init()
{
    unsigned char i;
    
    close_write_protect();
    for (i = 0; i < 7; i++)
    {
        ds1302_write(write_addr[i], time_buff[i]);
    }
    open_write_protect();
}

/**
 *  DS130打开写保护
 *  @param None
 *  @return None
 */
void open_write_protect(void)
{
    ds1302_write(0x8e, 0x00);       /**< 打开写保护 */ 
}

/**
 *  DS1302关闭写保护
 *  @param None
 *  @return None
 */
void close_write_protect(void)
{
    ds1302_write(0x8e, 0x00);       /**< 关闭写保护 */    
}
/**
 *  读取时间
 *  @param None
 *  @return None
 */
void ds1302_read_time()
{
    unsigned char i;
    
    for (i = 0; i < 7; i++)
    {
        time_buff[i] = ds1302_read(read_addr[i]);
    }
}

/**
 *  向DS1302写入命令
 *  @param [in] addr dat
 *  @return None
 */
static void ds1302_write(unsigned char addr, unsigned char dat)
{
    unsigned char i;
    
    DS_RST = 0;
    _nop_();
    DS_CLK = 0;
    _nop_();
    DS_RST = 1;
    _nop_();
    
    for (i = 0; i < 8; i++)         /**< 传送地址 */
    {
        DS_IO = addr & 0x01;
        addr >>= 1;
        DS_CLK = 1;                 /**< 上升沿读取数据 */
        _nop_();
        DS_CLK = 0;
        _nop_();
    }
    
    for (i = 0; i < 8; i++)         /**< 传送数据 */
    {
        DS_IO = dat & 0x01;
        dat >>= 1;
        DS_CLK = 1;
        _nop_();
        DS_CLK = 0;
        _nop_();
    }
    
    DS_RST = 0;
    _nop_();
}

/**
 *  DS1302读取命令
 *  @param [in] addr 
 *  @return None
 */
static unsigned char ds1302_read(unsigned char addr)
{
    unsigned char i;
    unsigned char dat, dat_dup;
    
    DS_RST = 0;
    _nop_();
    DS_CLK = 0;
    _nop_();
    DS_RST = 1;
    _nop_();
    
    for (i = 0; i < 8; i++)             /**< 读取命令 */
    {
        DS_IO = addr & 0x01;
        addr >>= 1;
        DS_CLK = 1;
        _nop_();
        DS_CLK = 0;
        _nop_();
    }
    _nop_();
    for (i = 0; i < 8; i++)             /**< 读取数据 */
    {
        dat_dup = DS_IO;
        dat = (dat >> 1) | (dat_dup << 7);
        DS_CLK = 1;
        _nop_();
        DS_CLK = 0;
        _nop_();
    }
    
    DS_RST = 0;
    _nop_();
    DS_CLK = 1;
    _nop_();
    DS_IO = 0;
    _nop_();
    DS_IO = 1;
    _nop_();
    
    return dat;
}

